package server

import (
	"github.com/emicklei/proto"
	"github.com/go-kratos/kratos/cmd/kratos/v2/pkg/golang"
	"path/filepath"
	"strings"
)

type Field struct {
	Name string
	Type string
}
type Message struct {
	Name   string
	Fields []*Field
}

type Object struct {
	rootPkg       string
	rootPath      string
	targetDir     string
	Filename      string
	Services      []*Service
	Messages      []*Message
	MessageRecord map[string]*Message
}

func NewObject(protoStr, targetDir string, s []*Service, msgs []*proto.Message) *Object {

	arrs := strings.Split(protoStr, "/")
	filename := strings.Split(arrs[len(arrs)-1], ".")[0]

	var (
		ms        []*Message
		msgRecord = make(map[string]*Message)
	)
	for _, v := range msgs {
		m := &Message{
			Name: v.Name,
		}
		for _, el := range v.Elements {
			field, ok := el.(*proto.NormalField)
			if !ok {
				continue
			}
			m.Fields = append(m.Fields, &Field{
				Name: field.Name,
				Type: field.Type,
			})
		}
		ms = append(ms, m)

		msgRecord[m.Name] = m
	}

	return &Object{
		targetDir:     targetDir,
		Filename:      filename,
		Services:      s,
		Messages:      ms,
		MessageRecord: msgRecord,
	}
}

func (o *Object) Gen() error {
	rootPkg, err := golang.GetParentPackage(targetDir)
	if err != nil {
		return err
	}
	o.rootPkg = rootPkg

	path, err := filepath.Abs(o.targetDir)
	if err != nil {
		return err
	}
	o.rootPath = path

	if err := o.domain(); err != nil {
		return err
	}

	if err := o.usecase(); err != nil {
		return err
	}

	return o.service()
}
